import { Byte } from '../../api/io/Byte';
import { ITimer } from '../../api/timer/ITimer';
import { IAsync } from '../../api/event/IAsync';



/**战报演员属性枚举*/
export const enum E_BattleReportActor {
	/**类型*/
	ACTOR_TYPE = 0,
	/**等级*/
	LEVEL = 1,
	/**模型*/
	MODEL = 2,
	/**昵称*/
	NICKNAME = 3,
	/**昵称配置ID*/
	CONFIG_NICKNAME = 4,
	/**配置id*/
	CONFIG_ID = 5,
	/**宠物站位 1 开始*/
	PET_POS = 6,
	/**枚举数量*/
	EnumCount = 7
}


/**战报演员*/
export class BattleReportActor {
	/**事件ID*/
	public static readonly EVENT_ID = 'STRUCT_DATA_BATTLE_REPORT_ACTOR_EVENT_ID';
	/**整体更新事件ID（部分只需要监听整体变化）*/
	public static readonly TOTAL_EVENT_ID = 'STRUCT_DATA_BATTLE_REPORT_ACTOR_TOTAL_EVENT_ID';
	/**缓存池*/
	private static POOL: BattleReportActor[] = [];

	/**创建入口*/
	public static create(json?: string): BattleReportActor {
		const c = this.POOL.pop() || new BattleReportActor();
		c._destroyed = false;
		c.resetProperty();
		if (json) {
			c.parse(json);
		}
		return c;
	}


	/**已释放*/
	protected _destroyed = false;
	/**类型 (uint8)*/
	protected _actorType: number;
	/**等级 (uint16)*/
	protected _level: number;
	/**模型*/
	protected _model: string;
	/**昵称*/
	protected _nickname: string;
	/**昵称配置ID (uint32)*/
	protected _configNickname: number;
	/**配置id (uint32)*/
	protected _configId: number;
	/**宠物站位 1 开始 (uint8)*/
	protected _petPos: number;


	/**构建函数-私有，防止外部创建*/
	private constructor() {
	}


	/**释放*/
	public destroy(): void {
		if (this._destroyed) {
			return;
		}
		this._destroyed = true;
		this.resetProperty(true);
		if (BattleReportActor.POOL.indexOf(this) === -1) {
			BattleReportActor.POOL.push(this);
		}
	}

	/**类型*/
	public get actorType() {
		return this._actorType;
	}


	/**类型*/
	public set actorType(v: number) {
		this._actorType = v;
	}


	/**等级*/
	public get level() {
		return this._level;
	}


	/**等级*/
	public set level(v: number) {
		this._level = v;
	}


	/**模型*/
	public get model() {
		return this._model;
	}


	/**模型*/
	public set model(v: string) {
		this._model = v;
	}


	/**昵称*/
	public get nickname() {
		return this._nickname;
	}


	/**昵称*/
	public set nickname(v: string) {
		this._nickname = v;
	}


	/**昵称配置ID*/
	public get configNickname() {
		return this._configNickname;
	}


	/**昵称配置ID*/
	public set configNickname(v: number) {
		this._configNickname = v;
	}


	/**配置id*/
	public get configId() {
		return this._configId;
	}


	/**配置id*/
	public set configId(v: number) {
		this._configId = v;
	}


	/**宠物站位 1 开始*/
	public get petPos() {
		return this._petPos;
	}


	/**宠物站位 1 开始*/
	public set petPos(v: number) {
		this._petPos = v;
	}



	/**通过枚举获取值*/
	public getV(k: E_BattleReportActor): any {
		switch (k) {
			case E_BattleReportActor.ACTOR_TYPE: return this._actorType;
			case E_BattleReportActor.LEVEL: return this._level;
			case E_BattleReportActor.MODEL: return this._model;
			case E_BattleReportActor.NICKNAME: return this._nickname;
			case E_BattleReportActor.CONFIG_NICKNAME: return this._configNickname;
			case E_BattleReportActor.CONFIG_ID: return this._configId;
			case E_BattleReportActor.PET_POS: return this._petPos;
			default: return null;
		}
	}


	/**通过枚举设置值*/
	public setV(k: E_BattleReportActor, v: any): void {
		switch (k) {
			case E_BattleReportActor.ACTOR_TYPE: this._actorType = v; break;
			case E_BattleReportActor.LEVEL: this._level = v; break;
			case E_BattleReportActor.MODEL: this._model = v; break;
			case E_BattleReportActor.NICKNAME: this._nickname = v; break;
			case E_BattleReportActor.CONFIG_NICKNAME: this._configNickname = v; break;
			case E_BattleReportActor.CONFIG_ID: this._configId = v; break;
			case E_BattleReportActor.PET_POS: this._petPos = v; break;
			default: break;
		}
	}


	/**初始化*/
	public resetProperty(fromDestroy = false): void {
		//类型
		this._actorType = 0;
		//等级
		this._level = 0;
		//模型
		this._model = '';
		//昵称
		this._nickname = '';
		//昵称配置ID
		this._configNickname = 0;
		//配置id
		this._configId = 0;
		//宠物站位 1 开始
		this._petPos = 0;
	}


	/**序列化*/
	public stringify(toString: boolean): string | any {
		const json: any = {};
		if (this._actorType) {
			json.actorType = this._actorType;
		}
		if (this._level) {
			json.level = this._level;
		}
		if (this._model) {
			json.model = this._model;
		}
		if (this._nickname) {
			json.nickname = this._nickname;
		}
		if (this._configNickname) {
			json.configNickname = this._configNickname;
		}
		if (this._configId) {
			json.configId = this._configId;
		}
		if (this._petPos) {
			json.petPos = this._petPos;
		}

		return toString ? JSON.stringify(json) : json;
	}


	/**反序列化*/
	public parse(jsonv: string | any): this {
		this.resetProperty();
		if (!jsonv) {
			return this;
		}
		const json = typeof (jsonv) === 'string' ? JSON.parse(jsonv) : jsonv;
		if (json.actorType) {
			this._actorType = json.actorType;
		}
		if (json.level) {
			this._level = json.level;
		}
		if (json.model) {
			this._model = json.model;
		}
		if (json.nickname) {
			this._nickname = json.nickname;
		}
		if (json.configNickname) {
			this._configNickname = json.configNickname;
		}
		if (json.configId) {
			this._configId = json.configId;
		}
		if (json.petPos) {
			this._petPos = json.petPos;
		}
		return this;
	}


	/**序列化-二进制*/
	public toBytes(byte: Byte): void {
		if (!byte) {
			return;
		}
		byte.writeUint8(this._actorType);
		byte.writeUint16(this._level);
		byte.writeString(this._model);
		byte.writeString(this._nickname);
		byte.writeUint32(this._configNickname);
		byte.writeUint32(this._configId);
		byte.writeUint8(this._petPos);
	}


	/**反序列化-二进制*/
	public fromBytes(byte: Byte): this {
		this.resetProperty();
		if (!byte) {
			return;
		}
		this._actorType = byte.readUint8();
		this._level = byte.readUint16();
		this._model = byte.readString();
		this._nickname = byte.readString();
		this._configNickname = byte.readUint32();
		this._configId = byte.readUint32();
		this._petPos = byte.readUint8();
		return this;
	}


	/**克隆*/
	public clone(): BattleReportActor {
		const byte = Byte.createFromPool();
		this.toBytes(byte);
		byte.pos = 0;
		const clonev = BattleReportActor.create().fromBytes(byte);
		Byte.recoverToPool(byte);
		return clonev;
	}


	/**处理更新*/
	public processUpdate(jsonv: string): void {
		if (!jsonv) {
			return;
		}

		const eventID = BattleReportActor.EVENT_ID;
		const us = JSON.parse(jsonv);

		for (let i = 0, len = us.length; i < len;) {
			const idx = us[i];
			//类型
			if (idx === E_BattleReportActor.ACTOR_TYPE) {
				const oldv = this._actorType;
				this._actorType = us[i + 1];
				IAsync.dispatch(eventID, idx, this._actorType, oldv);
				i += 2;
				continue;
			}
			//等级
			if (idx === E_BattleReportActor.LEVEL) {
				const oldv = this._level;
				this._level = us[i + 1];
				IAsync.dispatch(eventID, idx, this._level, oldv);
				i += 2;
				continue;
			}
			//模型
			if (idx === E_BattleReportActor.MODEL) {
				const oldv = this._model;
				this._model = us[i + 1];
				IAsync.dispatch(eventID, idx, this._model, oldv);
				i += 2;
				continue;
			}
			//昵称
			if (idx === E_BattleReportActor.NICKNAME) {
				const oldv = this._nickname;
				this._nickname = us[i + 1];
				IAsync.dispatch(eventID, idx, this._nickname, oldv);
				i += 2;
				continue;
			}
			//昵称配置ID
			if (idx === E_BattleReportActor.CONFIG_NICKNAME) {
				const oldv = this._configNickname;
				this._configNickname = us[i + 1];
				IAsync.dispatch(eventID, idx, this._configNickname, oldv);
				i += 2;
				continue;
			}
			//配置id
			if (idx === E_BattleReportActor.CONFIG_ID) {
				const oldv = this._configId;
				this._configId = us[i + 1];
				IAsync.dispatch(eventID, idx, this._configId, oldv);
				i += 2;
				continue;
			}
			//宠物站位 1 开始
			if (idx === E_BattleReportActor.PET_POS) {
				const oldv = this._petPos;
				this._petPos = us[i + 1];
				IAsync.dispatch(eventID, idx, this._petPos, oldv);
				i += 2;
				continue;
			}

			console.error('[Struct Data] can not find enum in BattleReportActor with idx = ' + idx + ', version maybe wrong.')
		}

		//全更事件
		ITimer.callLater(this, this.dispatchTotalUpdate);
	}


	/**比对不一致结果*/
	public getCompareInfo(other: BattleReportActor): string {
		if (!other) {
			return null;
		}

		const updates: any[] = [];

		if (this._actorType !== other._actorType) {
			updates.push(E_BattleReportActor.ACTOR_TYPE, this._actorType);
		}
		if (this._level !== other._level) {
			updates.push(E_BattleReportActor.LEVEL, this._level);
		}
		if (this._model !== other._model) {
			updates.push(E_BattleReportActor.MODEL, this._model);
		}
		if (this._nickname !== other._nickname) {
			updates.push(E_BattleReportActor.NICKNAME, this._nickname);
		}
		if (this._configNickname !== other._configNickname) {
			updates.push(E_BattleReportActor.CONFIG_NICKNAME, this._configNickname);
		}
		if (this._configId !== other._configId) {
			updates.push(E_BattleReportActor.CONFIG_ID, this._configId);
		}
		if (this._petPos !== other._petPos) {
			updates.push(E_BattleReportActor.PET_POS, this._petPos);
		}

		const jsonv = updates.length === 0 ? null : JSON.stringify(updates);
		return jsonv;
	}


	/**全部更新*/
	protected dispatchTotalUpdate(): void {
		IAsync.dispatch(BattleReportActor.TOTAL_EVENT_ID, this.getV(0));
	}

}
